typedef struct AATexpression_ *AATexpression;
typedef struct AATstatement_ *AATstatement;
typedef struct AATexpressionList_ *AATexpressionList;
typedef struct AATstatementList_ *AATstatementList;

typedef enum {	AAT_PLUS, AAT_MINUS, AAT_MULTIPLY, AAT_DIVIDE, AAT_MODULO, AAT_LT,
				AAT_GT, AAT_LEQ, AAT_GEQ, AAT_EQ, AAT_NEQ, AAT_NOT} AAToperator;


struct AATexpressionList_ {
  AATexpression first;
  AATexpressionList rest;
};


struct AATstatement_ {
  enum {AAT_MOVE, AAT_JUMP, AAT_CONDITIONALJUMP, AAT_PROCEDURECALL, AAT_SEQ, AAT_EMPTY, AAT_LABEL, AAT_RETURN, AAT_HALT, AAT_PROCEDUREDEF} kind; 
  union {
    struct {
      AATexpression lhs;
      AATexpression rhs;
    } move;
    Label jump;
    struct {
      AATexpression test;
      Label jump;
    } conditionalJump;
    struct {
      Label jump;
      AATexpressionList actuals;
    } procedureCall;
	struct {
		AATstatement body;
		int argsSize;
		Label start;
		Label end;
	} procedureDef;
    struct {
      AATstatement left;
      AATstatement right;
    } sequential;

    Label label;
  } u;
};

struct AATexpression_ {
  enum {AAT_MEMORY, AAT_OPERATOR, AAT_FUNCTIONCALL, AAT_CONSTANT, AAT_REGISTER, AAT_MEMALLOC} kind;
  union {
   // AATexpression memory;
    int constant;
    struct {
      AATexpression left;
      AATexpression right;
      AAToperator op;
    } operator;
    struct {
      Label jump;
      AATexpressionList actuals;
    } functionCall;
	struct {
	  Label blockName;
	  AATexpression memoryOffset;
	} memoryCell;	//used for memory allocation and memory reference
    Register reg;
  } u;
};


AATexpression AATMemoryAllocation(Label blockName, AATexpression dataSize);

AATexpression AATConstant(int constant);
AATexpression AATOperator(AATexpression left, AATexpression right, AAToperator op);

AATexpression AATRegister(Register reg);
AATexpression AATMemory(Label blockName, AATexpression memoryOffset);
AATexpressionList AATExpressionList(AATexpression first, AATexpressionList rest);
AATexpression AATFunctionCall(Label jump, AATexpressionList actuals);

AATstatement AATMove(AATexpression lhs, AATexpression rhs);
AATstatement AATSequential(AATstatement left, AATstatement right);
AATstatement AATEmpty();
AATstatement AATConditionalJump(AATexpression test,Label jump);
AATstatement AATJump(Label jump);
AATstatement AATLabel(Label);
AATstatement AATProcedureCall(Label jump, AATexpressionList actuals);
AATstatement AATProcedureDefinition(AATstatement body, int argsSize ,Label start, Label end);

